﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using AzukiMap.DataSource;
using Geotools.Geometries;
using AzukiMap.Renderer;
using AzukiMap.Tools.Logger;
using System.Windows.Controls;
using System.Windows;
using AzukiMap.Map;

namespace AzukiMap.Layer
{
    public abstract class VectorLayer : Layer, IVectorLayer
    {
        protected VectorSource _data;
        protected List<VectorLayerTheme> _layerThemes;
        protected VectorRendererSL _renderer;
        protected IVectorStyle _defaultStyle;

        public VectorSource Data
        {
            get { return _data; }
        }

        public int ThemeCount
        {
            get
            {
                return _layerThemes.Count;
            }
        }

        public List<string> Expressions
        {
            get
            {
                List<string> expressions = new List<string>();
                foreach (VectorLayerTheme theme in _layerThemes)
                {
                    expressions.Add(theme.Expression);
                }
                return expressions;
            }
        }

        public List<IVectorStyle> Styles
        {
            get
            {
                List<IVectorStyle> styles = new List<IVectorStyle>();
                foreach (VectorLayerTheme theme in _layerThemes)
                {
                    styles.Add(theme.Style);
                }
                return styles;
            }
        }

        public IVectorStyle DefaultStyle
        {
            get { return _defaultStyle; }
            set { _defaultStyle = value; }
        }

        public VectorLayer(VectorSource vectorData, MapCanvas mapCanvas, string name) 
            : base(mapCanvas, vectorData.DataType)
        {
            GTPolygon _extent = null;
            Init(vectorData, name, _extent);
        }

        public VectorLayer(VectorSource vectorData, MapCanvas mapCanvas, string name, GTPolygon extent) 
            : base(mapCanvas, vectorData.DataType)
        {
            Init(vectorData, name, extent);
        }

        void Init(VectorSource vectorData, string name, GTPolygon extent)
        {
            Name = name;
            MaxExtent = extent;
            IsDrawing = false;
            _data = vectorData;
            _layerThemes = new List<VectorLayerTheme>();
            _renderer = new VectorRendererSL(MapCanvas);
            _defaultStyle = new VectorStyle();
        }

        public int AddLayerTheme(string expression, IVectorStyle style)
        {
            int themeOrder = -1;
            VectorLayerTheme theme = new VectorLayerTheme(expression, style);
            _layerThemes.Add(theme);
            themeOrder = _layerThemes.IndexOf(theme);
            return themeOrder;
        } 

        public void RemoveLayerTheme(int themeOrder)
        {
            try
            {
                _layerThemes.RemoveAt(themeOrder);
            }
            catch (ArgumentOutOfRangeException ex)
            {
                Logger.Error("Theme order number is out of range on RemoveLayerTheme().\n" + ex.StackTrace);
            }
        }

        public void RemoveAllLayerThemes()
        {
            _layerThemes.Clear();
        }

        public void SetThemeExpression(int themeOrder, string expression)
        {
            try
            {
                _layerThemes[themeOrder].Expression = expression;
            }
            catch (ArgumentOutOfRangeException ex)
            {
                Logger.Error("Theme order number is out of range on SetThemeExpression().\n" + ex.StackTrace);
            }
        }

        public void SetThemeStyle(int themeOrder, IVectorStyle style)
        {
            try
            {
                _layerThemes[themeOrder].Style = style;
            }
            catch (ArgumentOutOfRangeException ex)
            {
                Logger.Error("Theme order number is out of range on SetThemeStyle().\n" + ex.StackTrace);
            }
        }

        public string GetThemeExpression(int themeOrder)
        {
            try
            {
                return _layerThemes[themeOrder].Expression;
            }
            catch (ArgumentOutOfRangeException ex)
            {
                Logger.Error("Theme order number is out of range on GetThemeExpression().\n" + ex.StackTrace);
                return null;
            }
        }

        public IVectorStyle GetThemeStyle(int themeOrder)
        {
            try
            {
                return _layerThemes[themeOrder].Style;
            }
            catch (ArgumentOutOfRangeException ex)
            {
                Logger.Error("Theme order number is out of range on GetThemeStyle().\n" + ex.StackTrace);
                return null;
            }
        }

    }
}
